Copyright © 1992,1993 Michael Balzer Oberon-2 source copyright © 1993 hartmut Goebel
Diese Dokumentation darf kopiert und weitergegeben werden solange die Copyright-Notiz und diese Erlaubnis unver�ndert auf allen Kopien enthalten ist.
Es wird keine Garantie gegeben, da� die Programme, die in dieser Dokumentation beschrieben werden, 100%ig zuverl�ssig sind. Sie benutzen diese Programme auf eigene Gefahr. Die Autoren k�nnen auf keinen Fall f�r irgendwelche Sch�den verantwortlich gemacht werden, die durch die Anwendung dieser Programme entstehen.
Das Paket ist “freely distributable”, aber das Copyright liegt weiterhin bei Michael Balzer. Dies bedeutet, da� es von jedem kopiert werden darf solange er nicht mehr als eine angemessene Kopiergeb�hr daf�r verlangt. Diese Geb�hr darf nicht h�her sein als US $5 oder 5 DM.
Dieses Limit gilt auch f�r deutsche Public-Domain H�ndler!!
Dieses Paket darf in Public-Domain Sammlungen aufgenommen werden, insbesondere in Fred Fishs Amiga Disk Library (CD ROM Versionen dieser Sammlung eingeschlossen). Die Distributionsdatei darf in Mailboxsystemen oder auf FTP Servern abgelegt werden. Wenn Sie dieses Paket weitergeben wollen, dann m�ssen Sie die originale Distributionsdatei ‘ARexxBox111.lha’ benutzen.
Dieses Paket darf nach Absprache mit dem Autor auch in eine Sammlung von Entwicklerwerkzeugen (wie z.B. das Native Developer’s Upgrade Kit von Commodore) aufgenommen werden.
Die Programme und der Quelltext (oder Teile davon) d�rfen auf keinen Fall auf irgendeiner Maschine benutzt werden, die f�r die Forschung, Entwicklung, Konstruktion, Tests oder Produktion von Waffen oder anderen milit�rischen G�tern benutzt wird. Dies gilt nat�rlich auch f�r alle Maschinen, die f�r das Training von Personen in irgendeiner der obengenannten T�tigkeiten benutzt werden.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Eines vorweg: Die ARexxBox ist ein Werkzeug von Programmierern f�r Programmierer. Wenn Sie Anwender sind brauchen Sie gar nicht weiter zu lesen, die ARexxBox ist f�r Sie dann von keinerlei Nutzen.
Eines der prim�ren Designziele bei der ARexxBox, und speziell nat�rlich dem erzeugten Code, war m�glichst nahe an die Vorgaben und Ideen des “User Interface Style Guide” von Commodore heranzukommen.
Wenn Sie dieses Buch (oder die Kapitel zu ARexx) noch nicht gelesen haben, w�re diese Lekt�re vor der Benutzung der ARexxBox erst einmal angebracht.
Meiner Meinung nach ist eine Normung der ARexx–Interfaces bez�glich Syntax und Verhalten dringend notwendig; es kann nicht angehen, da� der Anwender f�r jedes neue Programm erst wieder ein anderes Konzept und andere Befehle lernen mu�.
Allerdings sind einige der Ans�tze im Style Guide nicht mehr als das — Ans�tze. Speziell bei den Parametern der Standardfunktionen bleiben an vielen Stellen Fragen offen. Ich habe versucht, diese Stellen zumindest teilweise bei der �bernahme in die ARexxBox zu erg�nzen, wenn trotzdem Verst�ndnisprobleme auftreten bitte ich um Nachricht, am Besten sofort mit Verbesserungsvorschlag.
Die ARexxBox ist FreeWare, das hei�t unter den im Kapitel zu Copyright festgelegten Bedingungen frei verteilbare, aber urheberrechtlich gesch�tzte Software. Weder f�r die Box selbst, noch f�r den erzeugten Code m�ssen irgendwelche Lizenzen an die Autoren gezahlt werden.
Wenn Sie den von der ARexxBox erzeugten Code direkt oder ver�ndert in ihren Applikationen einsetzen, dann mu� dies im About–Fenster und in der Dokumentation erw�hnt werden. Au�erdem w�rde ich mich freuen, wenn Sie mir eine kurze Nachricht dar�ber zukommen lassen (bevorzugt per EMail), eine �bersicht �ber die implementierten ARexx–Befehle w�re auch nicht schlecht, mu� aber nicht sein.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Der Autor kann unter folgenden Adressen erreicht werden:
Michael Balzer Wildermuthstra�e 18 W-5828 Ennepetal GERMANY
An der Uni: balzer@heike.informatik.uni-dortmund.de Zu Hause: bilbo@bagsend.aworld.de oder im Z-Netz m.balzer@aworld.zer oder von Fido aus Michael Balzer of 2:241/5604.19
Die Fido–Adresse wurde noch nie getestet, wenn kein Reply kommt bitte andere Adresse benutzen.
Bei Fragen zum Oberon-2–Source wenden Sie sich am besten direkt an dessen Autor:
hartmut Goebel Aufse�platz 5 W-8500 N�rnberg 40 neue Postleitzahl ab 1. Juli 1993: 90459 GERMANY
Zu Hause: hartmut@oberon.nbg.sub.org oder im Z-Netz (eher selten) hartmut@asn.zer oder von Fido aus Harmut Goebel of 2:246/81.1
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die Wichtigkeit und Leistungsf�higkeit von ARexx auf dem Amiga d�rfte Ihnen schon klar sein, sonst w�rden Sie sich wahrscheinlich nicht dieses Manual durchlesen. Ich mu� Sie also nur noch davon �berzeugen, da� die ARexxBox das richtige Werkzeug zum Erstellen der ARexx–Anbindung f�r Ihr Programm/Projekt ist ;-).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die ARexxBox (inspiriert von der GadToolsBox von Jan van den Baard) ist ein Tool, das das Erstellen eines ARexx–Interfaces f�r ein Programm extrem erleichtert und vereinfacht und dabei ein ARexx–Interface erzeugt, das den Anforderungen des “User Interface Style Guide” gen�gt.
Die F�higkeiten in Stichpunkten:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An die Hardware werden so gut wie keine Anforderungen gestellt, die ARexxBox sollte auf jedem Amiga laufen.
Naja, eine Anforderung wird gestellt: Da das ARexxBox–Fenster mehr als 200 Zeilen hoch ist, mu� eine NTSC–MedRes–Workbench im Overscan betrieben werden damit das Fenster ge�ffnet werden kann. Alternativ k�nnte man auch einen 6 oder 7 Punkte gro�en Systemfont einstellen.
Da Programmierer aber naturgem�� mit h�heren Aufl�sungen arbeiten, stellt sich dieses Problem wohl kaum.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Bedingung zur Lauff�higkeit sowohl der ARexxBox als auch des erzeugten Codes ist mindestens AmigaOS 2.04, d.h. mindestens Kickstart 37.175 und Workbench 37.67.
Sie sollten sich au�erdem eine Kopie von Nico Francois’ reqtools.library besorgen, wenn Sie noch keine haben. Diese wird nur f�r die Box ben�tigt, der erzeugte Code benutzt sie nicht.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Um den erzeugten Source zu kompilieren ben�tigen Sie einen ANSI–C–Compiler, der auch Funktionen aus der ‘amiga.lib’ von Commodore importieren und verarbeiten kann.
Sie ben�tigen mindestens Version 37.32 (12.11.91) der ‘amiga.lib’, um den erzeugten Code linken zu k�nnen. Diese Version ist im Native Developer’s Upgrade Kit V37.4 (11/91) (erh�ltlich bei Hirsch&Wolf) enthalten und wird auch schon bei manchen Compilern mitgeliefert.
Sie k�nnen auch ohne die ‘amiga.lib’ auskommen. Ich habe die
ben�tigten Funktionen (GetRexxVar
und SetRexxVar
)
reassembliert und dem Paket beigelegt. Der Aztec C Compiler braucht sehr
lange, um Funktionen aus der ‘amiga.lib’ zu extrahieren, daher
verk�rzt das Linken mit diesem Modul den Linkvorgang erheblich.
Andererseits kann ich nat�rlich f�r die Kompatibilit�t der reassemblierten Funktionen nicht garantieren, und von zuk�nftigen Verbesserungen in der ‘amiga.lib’ machen Sie damit auch keinen Gebrauch.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
F�r den Oberon-2–Source ben�tigen Sie AmigaOberon V3.0 oder h�her.
Der Source baut auf einer Klassenbibliothek auf, die im Lieferumfang des Compilers nicht enthalten ist, ebenso einge andere ben�tigte Module. Diese befinden sich jedoch alle mit Quelltext im ARB-Paket.
Das Modul RVI stellt einen Schnittstelle zu einem Teil der amiga.lib her. Diese mu� dann beim Linken mit angegeben werden, z. B.
OLink RxTest OBJ oberon:obj/amiga.lib
Mehr zur amiga.lib finden Sie oben im Abschnitt C–Source.
Sollten Sie das Object-File “rexxvars.o” aus einem der ARexx Entwickler-Kits haben, k�nnen Sie dieses gleiche mit der Option $JOIN an das Object-File des Moduls RVI anh�ngen. Die gesonderte Angabe der amiga.lib beim Linken entf�llt dann. Wegen der Gr��e der amiga.lib empfiehlt sich dieses Verfahren mit dieser nicht.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Im Prinzip ist bei der ARexxBox keine Installation n�tig. Nur im Oberon-Teil sind einige ben�tigte Module (2), die nicht von der Box selbst erzeugt werden. Diese sollten an eine geeignete Stelle kopiert werden, wo sie der Compiler auch findet.
Wo Sie den Rest unterbringen (z.B. die Dokumentation und die ARexxBox selbst) ist Ihnen �berlassen.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An der Bedienung der ARexxBox ist absolut nichts ungew�hnliches. Sie sollten auf Anhieb damit zurechtkommen, wenn Sie jemals mit einer Amiga–Applikation gearbeitet haben.
Bevor Sie mit der Eingabe von Befehlen beginnen, sollten Sie vielleicht das
Kapitel zum Konzept durchlesen. Als Anschauungsbeispiel k�nnen Sie z.B.
erst mal aus dem Verzeichnis ‘arb’ die Datei ‘Misc.arb’ laden.
Klicken Sie in der linken Liste (Commands) auf die Zeile GETATTR
.
Die beiden rechten Listen f�llen sich daraufhin mit den Parametern und
Resultaten des Kommandos GETATTR
. Jedes Element jeder Liste kann
�ber das Stringgadget unter der Liste ver�ndert werden.
6.1 Eingabe | Vorgehensweise f�r einen neuen Befehl | |
6.2 MsgPort Basename | ||
6.3 CommandShell | ||
6.4 Merge in | ||
6.5 Print | ||
6.6 Generate Source | C oder Oberon, das ist hier die Frage | |
6.7 Clipboard | Cut, Copy und Paste |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
F�r die Eingabe einer Befehlsdefinition empfiehlt sich folgende Vorgehensweise: Taste <N> dr�cken, Namen des ARexxbefehls eingeben und mit <RETURN> best�tigen. Die ARexxBox wandelt den Namen in Gro�buchstaben und unzul�ssige Zeichen in Underscores (‘_’) um und pr�ft den Namen auf Eindeutigkeit. Falls schon ein solcher Befehl existiert kann der Name korrigiert werden.
Danach legen Sie die Argumente fest. F�r jedes Argument dr�cken Sie die Taste <E> und geben dann den Namen ein. Auch dieser wird auf Eindeutigkeit gepr�ft.
Genau so verfahren Sie f�r die Resultatenliste, nur da� das Shortcut f�r ein neues bzw. weiteres Resultatfeld dort die Taste <W> ist.
Argumente und Resultate k�nnen entweder direkt nach der Eingabe oder sp�ter nach dem Anw�hlen per Mausklick in der Liste mit den jeweiligen ‘up’– und ‘do’–Gadgets nach oben bzw. unten verschoben werden oder mit der jeweiligen ‘Remove’–Funktion gel�scht werden.
Die Typen der Argumente und Resultate werden im ReadArgs()–Stil (siehe AutoDocs) an die Namen angeh�ngt, also zum Beipiel ARG1/K/N oder LISTE/M. Bei den Resultatfeldern sind nur die Switches /M (f�r Liste) und /N (f�r Numerisch) erlaubt.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Der ‘MsgPort Basename’ ist der Default–Basisname f�r alle von der Applikation er�ffneten ARexx–Ports. Bei Bedarf (schon existentem Port unter dem Namen) wird so lange eine steigende Nummer an den Basisnamen angeh�ngt bis der Port ohne Konflikt ge�ffnet werden kann.
Auf jeden Fall sollte aber die Applikation (wie im Demo–Programm gezeigt) ein Argument bzw. Tooltype namens “PORTNAME” verstehen, damit der Benutzer Einflu� auf die Namensgebung nehmen kann. Ein solcher per Argument festgelegter Portname wird zum neuen Basisnamen und ggf. auch (automatisch) entsprechend durch eine angeh�ngte Nummer erg�nzt.
Der ‘MsgPort Basename’ wird au�erdem als Standard–Dateiextension f�r von der Applikation gestartete ARexx–Skripten eingesetzt. Dies ist unabh�ngig von einem eventuell vom Anwender gesetzten Portnamen.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Mit diesem Gadget bestimmen Sie, ob bei der Sourcegenerierung Code f�r eine CommandShell erzeugt werden soll. Diese Option sollte im Normalfall ruhig eingeschaltet sein, da die CommandShell–Funktionen auch zum Ausf�hren externer Makros n�tzlich sein k�nnen.
F�r Oberon wird der CommandShell–Source immer erzeugt.
Die CommandShell ist eine Art Shell, die s�mtliche ARexx–Befehle einer Applikation ausf�hren kann, als w�ren diese von ARexx gekommen. Dabei werden die Resultate der Befehle in lesbarer Form in dem Shellfenster ausgegeben.
Die CommandShell eignet sich z.B. daf�r, mal schnell ein ARexx–Kommando abzusetzen ohne gleich ARexx selbst zu bem�hen. Man kann hier auch einige Befehle erlauben, die nur dem ge�bten Anwender zur Verf�gung stehen sollten.
Wenn man die CommandShell mit einer Datei als Eingabekanal versorgt, arbeitet sie die darin enthaltenen Kommandos Zeile f�r Zeile ab. Auf diese Art und Weise kann sie auch f�r Makros verwendet werden.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Diese Funktion erg�nzt die im Speicher befindliche Kommandoliste um die ARexx–Kommandos aus dem auszuw�hlenden ARexxBox–File, die noch nicht in der Liste vorhanden sind.
Dadurch ist es m�glich, sich Pakete von ARexx–Kommandos f�r verschiedene Zwecke anzulegen, und diese dann nach Bedarf zu kombinieren.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Soll eine Dokumentationshilfe sein. F�r jeden Befehl wird der Name, die Syntax und die Resultate ausgegeben.
Vorschl�gen f�r eine andere und bessere Formatierung gegen�ber bin ich sehr aufgeschlossen.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Hiermit wird der Sourcegenerator gestartet. Der im FileRequester eingegebene Name wird um die evtl. vorhandene Extension (‘.c’, ‘.h’ oder ‘_rxif.c’ bzw. f�r Oberon ‘.mod’) gek�rzt, dann wird nach ein paar Sicherheitschecks (haupts�chlich, ob durch die Generierung ein anderes Modul unabsichtlich �berschrieben werden k�nnte) mit der Sourcegenerierung begonnen.
Jegliche Generierung findet zun�chst einmal in ‘T:’ statt, um der M�glichkeit eines Absturzes w�hrend des Schreibens zumindest teilweise den Schrecken zu nehmen. Erst nach korrektem Abschlu� der Generierung werden die Dateien an ihren tats�chlichen Bestimmungsort kopiert.
Wenn beim Kopieren irgendein Fehler passiert, werden die Originaldateien in ‘T:’ nicht gel�scht, so da� Sie diese zur Not noch von Hand an einen sicheren Ort kopieren k�nnen.
Beim Generieren des Sources wird f�r alle Kommandos der Status auf “Alt” gesetzt. Wenn ein Kommando in der Box ver�ndert wird, wird der Status auf “Neu” gesetzt. Daran erkennt der Sourcegenerator, bei welchen Kommandos sich eventuell etwas ge�ndert hat, und erzeugt vor den Interfacefunktionen im Source einen Kommentar (“ATT: Interface changed!”), der darauf hinweist.
Wo dieser Kommentar steht, sollte der Programmierer vor dem n�chsten Compilerlauf die Konsistenz des Interfaces und der RXD–Struktur mit der tats�chlichen (eventuell auf einem �lteren Interface basierenden) Routine �berpr�fen und wo n�tig den Source den neuen Gegebenheiten anpassen.
Damit die �nderung des Status’ der Kommandos auch gespeichert wird (mu� ja �ber mehrere Sitzungen hinweg erhalten bleiben), wird beim Generieren des Sources auch das gesamte Projekt als ‘ge�ndert’ gekennzeichnet. Sinnvollerweise speichern Sie das Projekt einfach direkt nach der Sourcegenerierung.
Zur Zeit stehen zwei Sourcegeneratoren zur Verf�gung, einer f�r C (von mir) und einer f�r Oberon (von hartmut Goebel). Bei Fragen bez�glich Oberon bitte an hartmut wenden.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Cut, Copy und Erase beziehen sich entweder auf das aktuelle Kommando oder auf einen vorher festgelegten Bereich.
Um einen Bereich zu markieren, w�hlen Sie “Mark Range” an, klicken dann zuerst auf den ersten Befehl des gew�nschten Bereiches, und dann auf den letzten. Alle Befehle vom ersten bis zum letzten w�rden nun bei einem anschlie�enden Copy kopiert werden.
Die Anwahl eines beliebigen Befehls l�scht die Bereichsmarkierung.
Paste setzt nur die Befehle in die Datei ein, die vorher noch nicht darin waren (wie Merge).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Neben der Style–Guide–Konformit�t war ein anderes prim�res Designziel der ARexxBox, dem Programmierer die Handhabung des ARexxPorts so leicht wie m�glich zu machen.
7.1 Initialisierung | Port �ffnen | |
7.2 Kommandos von ARexx | Dispatcher und Interfacefunktionen | |
7.3 Expandierung von Befehlen | ExpandRXCommand() und Externe Befehle | |
7.4 Kommandos an ARexx | SendRexxCommand() | |
7.5 CloseDown | Port schlie�en |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Zum �ffnen des ARexxPorts dient die Funktion SetupARexxHost, die einen
Zeiger auf ein Objekt vom Typ struct RexxHost
zur�ckgibt. Dieser
Zeiger ist als eine Art FileHandle f�r den ARexxPort zu verstehen, alle
weiteren ARexx–Funktionen der ARexxBox ben�tigen diesen Zeiger.
In Oberon-2 liefert SetupARexxHost ebenfalls einen Pointer, der als Empf�nger (engl. “receiver”) der Methoden dient.
Somit beziehen sich auch alle Operationen immer auf einen bestimmten Port (eine Applikation kann ja durchaus auch mehrere Ports �ffnen, z.B. k�nnte ein Texteditor f�r jedes offene File einen Port �ffnen).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
W�hrend des Betriebs mu� die Applikation im einfachsten Fall nichts weiter tun, als bei einer am ARexxPort eingegangenen Message die Funktion ARexxDispatch aufzurufen. Diese holt sich selbst�ndig alle Messages des angegebenen RexxHosts und f�hrt alle n�tigen Schritte durch, um die Requests zu befriedigen.
Zu jedem Kommando geh�rt eine Interface–Funktion, deren Adresse in der Kommandoliste vermerkt ist. Diese Interface–Funktion enth�lt den eigentlichen Code zum Befehl, �blicherweise ruft dieser nach einer Parameter�berpr�fung die entsprechenden Kernfunktionen auf. Alles was Sie als Programmierer tun m�ssen, ist das Schreiben dieser Interfacefunktion — wobei die Box bei neuen Funktionen nat�rlich ein Leermuster erzeugt.
Die Interfacefunktion bekommt die Parameter des Kommandos �ber eine speziell angelegte Datenstruktur, f�hrt die Operation durch und gibt �ber dieselbe Datenstruktur eventuelle Resultate an die ARexxBox–Routinen zur�ck. Die ARB–Routinen sorgen dann daf�r, da� auch das Resultat Style–Guide–konform an ARexx zur�ckgeschickt wird.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Um den ALIAS–Befehl (Standard) und andere M�glichkeiten wie Makros zu unterst�tzen gibt es einen Callback, der vom Parser aufgerufen wird, bevor ein als unbekannt eingestuftes Kommando einen Fehler erzeugt.
Der Parser ist der Teil der ARexxBox, der versucht, zu erkennen um welches Kommando es sich bei einer Message handelt. Wenn diese Erkennung fehlschl�gt, ruft er die Funktion ExpandRXCommand() auf, die z.B. eine Liste von Aliases durchgehen kann und eine geeignete Substitution vornimmt.
Anschlie�end versucht der Parser noch einmal, das Kommando zu ermitteln.
Wenn dieser zweite Anlauf ebenfalls fehlschl�gt, wird das Kommando an ARexx weitergereicht (das urspr�ngliche, nicht das expandierte). Falls ein externes Skript unter dem Namen existiert wird dieses also v�llig transparent aufgerufen. Auch das Resultat eines solchen externen Befehls wird korrekt an den urspr�nglichen Caller zur�ckgegeben.
Demonstration: Wechseln Sie in das Verzeichnis ‘test’ und starten Sie ‘test’. Beenden Sie die CommandShell durch EOF (<C-\>) und geben Sie in einer anderen Shell folgendes Kommando ein:
rx "options results; address 'arbtest'; test 'FooBar'; say result"
Da das Testprogramm keinen internen Befehl “test” kennt, wird das externe Skript ‘test.arbtest’ gestartet, welches im Ausgabefenster des Testprogramms eine Meldung ausgibt und dann den String “Testtext!” zur�ckgibt (ja, ich wei�, sehr einfallsreich).
Erst wenn auch kein Skript unter dem gegebenen Namen existiert wird der Befehl endg�ltig als “unbekannt” eingestuft und ein Fehler erzeugt.
Hier noch mal der Ablauf f�r ein Kommando:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die Applikation kann nat�rlich auch beliebig eigene Kommandos an ARexx senden, dazu stehen einige Hilfsfunktionen zur Verf�gung (siehe SendRexxCommand).
Da solche Kommandos prinzipiell (als Messages) asynchron ablaufen, bietet die ARexxBox die M�glichkeit, beim Eintreffen eines Replies zu solch einem Kommando eine spezielle Funktion aufzurufen, die z.B. das Resultat des Kommandos auswerten kann. Dabei mu� nat�rlich der Programmierer Sorge tragen, da� er im nachhinein einen Reply dem richtigen Kommando zuordnen kann (siehe Einbindung).
Um sp�te R�ckmeldungen von gesendeten Kommandos nicht ins Leere laufen zu lassen z�hlen die Boxroutinen s�mtliche ausgehenden Kommandos, der Port bleibt so lange offen, wie noch R�ckmeldungen erwartet werden (siehe CloseDown).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Das Gegenst�ck zu SetupARexxHost ist dann folgerichtig CloseDownARexxHost. Diese Funktion schlie�t den Port und gibt alle angeforderten Ressourcen frei.
Wenn Kommandos an ARexx geschickt wurden, kann sich das endg�ltige Schlie�en des Ports verz�gern, da die Box dann zun�chst auf alle noch ausstehenden Replies warten mu�. Wenn w�hrend dieser Wartephase neue Kommandos am Port eintreffen, werden diese sofort mit dem Fehler “Host closing down” an ARexx zur�ckgeschickt.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die ARexxBox erzeugt Source, der im Prinzip ohne jede �nderung sofort compilierbar sein sollte. S�mtliche Interfacefunktionen m�ssen theoretisch im Code zumindest als Leerfunktionen generiert worden sein.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
F�r C werden f�nf Dateien erzeugt:
CommandShell
) nichts �ndert.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
F�r Oberon werden vier Dateien erzeugt:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die ARexxBox generiert im Rexx–Interface–Modul einige spezielle
Kommentarzeilen der Form /* $ARB: ... */
(bei Oberon (*
!ARB: ... *)
, die Sie nicht ver�ndern d�rfen.
Am Anfang des Interface–Moduls steht eine Kommentarzeile, durch die die ARexxBox pr�fen kann, ob dieses Sourcemodul zur aktuellen Interfacedefinition geh�rt.
Zu jeder Interfacefunktion geh�ren zwei Kommentarzeilen, alles zwischen diesen beiden wird als zu der Interfacefunktion geh�rend betrachtet und komplett nach rxifstore ausgelagert, wenn die Funktion nicht mehr ben�tigt wird. Wenn Sie also spezielle Variablen und Funktionen zu einer Interfacefunktion ben�tigen, denken Sie daran, diese zwischen den beiden Kommentarzeilen zu definieren, so bleibt alles beisammen.
Wenn die Definition eines Kommandos ver�ndert wurde, erzeugt die Box vor der entsprechenden Interfacefunktion eine Kommentarzeile der Form “ATT: Interface changed!”. Dieser Kommentar darf gel�scht werden, allerdings sollte man wirklich erst pr�fen, ob der Code an die neuen Argumente bzw. Resultate angepa�t werden mu�.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jede Interfacefunktion besteht aus drei Teilen,
die in dieser Reihenfolge von den ARexxBox–Routinen aufgerufen werden.
Die erste Phase dient dabei der Allokierung und Initialisierung des Speichers f�r die Datenstruktur, in der Parameter und Resultate zwischen Interfacefunktion und ARB–Routinen hin und her transportiert werden.
Man kann diese Phase auch f�r andere Initialisierungen benutzen, z.B. Allokierung von lokalem Pufferspeicher o.�..
Die zweite Phase f�hrt die eigentliche Operation durch und benutzt dabei die Parameter aus der in der ersten Phase allokierten Transferstruktur und setzt die eventuell anfallenden Resultate ebenfalls dort ein.
Es gibt zwei Felder in jeder Transferstruktur, rc und rc2. Diese beiden entsprechen den normalen Returncodes, die jeder ARexxbefehl erzeugen kann. Die ARexxBox nimmt dabei allerdings noch eine kleine Erweiterung vor (siehe Fehler).
Nach der Ausf�hrung von Phase zwei �bernimmt die ARexxBox–Routine die Resultate und schickt diese an ARexx zur�ck. Dann wird noch Phase drei aufgerufen, die der Interfacefunktion Gelegenheit gibt, angeforderte Ressourcen wieder freizugeben.
Einige Beispiele, wie Interfacefunktionen aufgebaut sein sollten und funktionieren, finden Sie im Verzeichnis ‘rxif’, speziell die HELP–Funktion d�rfte ein gutes einf�hrendes Beispiel abgeben.
Hier mal die konkrete Struktur einer Interfacefunktion:
void rx_help( struct RexxHost *host, struct rxd_help **rxd, long action, struct RexxMsg *rexxmsg ) { struct rxd_help *rd = *rxd; /* zur Vereinfachung und f�r lokale Erweiterungen */ struct rxs_command *rxc; /* lokale Variablen */ int cnt = 1; switch( action ) { case RXIF_INIT: /* Erste Phase! */ /* Hier wird nun die Transferstruktur allokiert */ *rxd = calloc( sizeof *rd, 1 ); /* Defaultwerte setzen wir hier mal nicht, also */ break; case RXIF_ACTION: /* Zweite Phase! */ /* Hier wird gearbeitet */ if( rd->arg.prompt ) { rd->rc = -10; rd->rc2 = (long) "Prompt option not yet implemented"; return; } usw. usf., unter anderem werden hier die Allokationen rd->res.commanddesc = malloc( ... ) und rd->res.commandlist = [calloc]; gemacht, die in Phase drei wieder freigegeben werden m�ssen. break; case RXIF_FREE: /* Dritte und letzte Phase! */ /* Angeforderten Speicher zur�ckgeben */ if( rd->res.commanddesc ) free( rd->res.commanddesc ); if( rd->res.commandlist ) free( rd->res.commandlist ); /* Transferstruktur freigeben */ free( rd ); break; } /* Zur�ck zum Dispatcher */ return; }
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Wenn Sie in einer Interfacefunktion lokalen Speicher ben�tigen, sollten Sie keinesfalls auf statische oder globale Variablen zur�ckgreifen — denken Sie immer daran, da� bei mehreren Ports ein und dieselbe Interfacefunktion quasi gleichzeitig mehrfach in Benutzung sein kann. Au�erdem widersprechen lokale statische Variablen jedem objektorientierten Design (und w�rden z.B. bei Oberon schon Probleme bereiten).
Ein einfacher Trick verschafft Ihnen beliebige lokale Speicher: Erweitern Sie einfach die Transferstruktur am Ende um die gew�nschten Felder. Beispiel:
void rx_rx( struct RexxHost *host, struct rxd_rx **rxd, long action, struct RexxMsg *rexxmsg ) { struct { /* Einbettung der Originalstruktur */ struct rxd_rx rd; /* Es folgen die Erweiterungen */ long tempval; char *tempbuffer; ... } *rd = (void *) *rxd; ...
Oder in Oberon:
PROCEDURE Rx * (host: rxh.RexxHost; VAR rxd: rxh.RXDPtr; action: INTEGER); VAR rd: POINTER TO RECORD (rxdRx) (* Erweiterung der Originalstructur *) tempval: LONGINT; tempbuffer: BT.DynString; ... END; ...
Wie man sieht wurde hier eine lokale Erweiterung der Struktur rxd_rx vorgenommen, die ‘lokale’ Variablen (tempval und tempbuffer) zur Verf�gung stellt. Da die Transferstruktur inklusive der Erweiterung in der ersten Phase allokiert und erst in der letzten freigegeben wird, steht das zus�tzliche Feld dazwischen (w�hrend der zweiten Phase) konfliktfrei zur Verf�gung.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Im Verzeichnis ‘rxif’ finden Sie einige Beispielbefehle bzw. die Interfacefunktionen dazu. Einige davon sind quasi gebrauchsfertig, z.B. braucht der HELP–Befehl nur eine anwendungsspezifische graphische Oberfl�che.
Wenn Sie einen allgemein brauchbaren (sprich applikationsunabh�ngigen) Befehl geschrieben haben und diesen auch den anderen ARexxBox–Benutzern zur Verf�gung stellen wollen, dann schicken Sie mir bitte die Befehlssyntax und den Source.
Mir schwebt eine Sammlung von Standardbefehlen vor, die ohne gro�en Aufwand in ein beliebiges Programm eingebunden werden k�nnen, so eine Bibliothek von ARexx–Befehlen w�rde die ARexx–Interfaceentwicklung noch weiter vereinfachen.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Das Konzept der ARexxBox orientiert sich sehr eng an den Ideen und Vorschl�gen aus dem Style Guide.
Eine wichtige Grundlage ist hierbei, da� die Argumente der ARexx–Befehle genau so funktionieren und aussehen sollen, wie die Argumente von Shellbefehlen. Das setzt die ARexxBox dann auch folgerichtig um, indem zum Parsen der Parameter eines konkreten Befehls die DOS–Funktion ReadArgs() benutzt wird.
Zun�chst einmal sollten Sie nun das Kapitel zu ReadArgs durchlesen.
Sobald mindestens ein Resultat vorgesehen ist, erzeugt die ARexxBox automatisch zwei weitere Argumente (erst bei der Sourcegenerierung, in der Box werden diese nicht angezeigt): VAR und STEM.
Der Anwender kann durch VAR und STEM steuern, in welcher Form die Resultate eines Befehls in ARexx–Variablen abgelegt werden. Es gibt zwei solche Formen, die eine gibt s�mtliche Resultate in einer Variable zur�ck, die andere benutzt eine Stem–Variable um die einzelnen Resultatfelder einzelnen Stem–Feldern zuzuweisen.
Wenn weder VAR noch STEM spezifiziert wurde, wird die Form der R�ckgabe in
einer Variable benutzt, und zwar in der Standardvariable RESULT
.
Dabei besteht der Variableninhalt einfach aus der Verkettung aller
Ergebnisfelder, wobei die einzelnen Felder durch Leerzeichen getrennt
sind.
Sobald strukturierte R�ckgaben erforderlich sind, sollte die STEM–R�ckgabe verwendet werden.
VAR und STEM schlie�en sich nicht gegenseitig aus, beide R�ckgabemethoden
k�nnen kombiniert werden. Es wird nur kein RESULT
mehr erzeugt,
sobald eine dieser beiden Methoden explizit vom Anwender gew�hlt wird.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Aus Gr�nden der Konsistenz benutzt die ARexxBox f�r Resultate von Befehlen exakt die gleichen Konventionen wie f�r Argumente, mit der Einschr�nkung, da� nicht typgebende Switches (wie </A> oder </K>) ignoriert werden. Au�erdem wird der Typ Bool (</S> und </T>) nicht unterst�tzt, benutzen Sie stattdessen Integer (flexibler da ein Bool immer in der Ausgabe auftauchen w�rde, ein Integer nur wenn er gesetzt wurde).
Konkret gilt folgende Typ�quivalenz f�r die Resultate:
FOOBAR
ist ein String
FOOBAR/M
ist ein Array von Strings
FOOBAR/N
ist ein Integer (oder Bool)
FOOBAR/N/M
ist ein Array von Integern
Das bedeutet, da� auch bei den Resultaten (die ja von Ihrer Interfacefunktion erzeugt werden!) exakt die gleichen Typen erwartet werden, wie bei den Argumenten. S�mtliche Resultatfelder sind damit nat�rlich auch optional.
Nehmen wir mal ein konkretes Beispiel: �ffnen Sie in der Box die Datei
‘arb/Other.arb’ und w�hlen Sie den Befehl HELP
aus. Sie sehen,
da� der Help–Befehl offensichtlich zwei Resultate zul��t, einen einfachen
String (COMMANDDESC
) und ein Array von Strings (COMMANDLIST
).
Das bedeutet, da� die ARexxBox f�r diesen Befehl folgende Felder als
Resultatfelder in der Struktur rxd_help
(Transferstruktur) erzeugen
wird:
In C:
char *commanddesc; char **commandlist;
In Oberon (die Typbezeichner wurden f�r dieses Beispiel aufgel�st):
commanddesc: BasicTypes.DynString; commandlist: POINTER TO ARRAY OF BasicTypes.DynString;
Ihr Help–Befehl kann nun beliebige dieser beiden Felder setzen, indem er ihnen korrekte Werte zuweist, also z.B.
static char *myarray[4] = { "foo", "bar", "dubidu", NULL }; rxd->res.commanddesc = "Blafasel"; rxd->res.commandlist = myarray;
In Oberon mu� dies etwas anders gemacht werden, da die L�ngeninforamtion ebenfalls ben�tigt wird. Daf�r ben�tigen die Listen kein abschlie�endes NIL:
rxd.res.commanddesc := MoreStrings.CopyString("Blafasel"); NEW(rxd.res.commandlist,3); (* drei Eintr�ge *) rxd.res.commandlist[1] := MoreStrings.CopyString("foo"); rxd.res.commandlist[2] := MoreStrings.CopyString("bar"); rxd.res.commandlist[3] := MoreStrings.CopyString("dubidu");
(Anm.: Der normale HELP–Befehl erzeugt in Abh�ngigkeit von den Parametern immer nur eins der beiden Resultate, aber es w�re durchaus m�glich, beide Felder zu besetzen.)
Die ARexxBox k�mmert sich nun darum, die Resultate Style–Guide–konform an ARexx zur�ckzugeben: Integers werden in Strings umgewandelt, bei Arrays werden die Eintr�ge gez�hlt und die Anzahl gefolgt von den einzelnen Eintr�gen des Arrays zur�ckgegeben.
Sie k�nnen das Verhalten leicht ausprobieren: Starten Sie das Programm
‘test/test’ und geben Sie in der CommandShell help
ein. Ohne
Parameter gibt der Help–Befehl die Liste der Kommandos aus, benutzt also
nur das Feld rxd->res.commandlist
.
Die Ausgabe enth�lt die Anzahl der Listenelemente gefolgt von den Elementen
selbst. Sie sehen nun das Format, in dem das Resultat bei einer
ARexx–Anforderung in der Rexx–Variablen RESULT gelandet w�re. Dieses
Format k�nnen Sie mit dem Schl�sselwort VAR
in eine beliebige
Variable umlenken.
Geben Sie nun help stem kl.
ein. Bei einer ARexx–Anforderung w�re
die Stem–Variable kl genau so belegt worden wie angezeigt, d.h. bei
Arrays wird vorab ein Element Resultatname.COUNT
angelegt, dem die N
Elemente der Liste mit jeweils Benennung Resultatname.N
folgen.
Im obigen Beispiel w�rde das Resultat also lauten:
In VAR–Form:
"BlaFasel 3 foo bar dubidu"
In STEM–Form mit der Wurzel hr (sinnvoller wegen der strukturierten R�ckgabewerte):
hr.COMMANDDESC = "BlaFasel" hr.COMMANDLIST.COUNT = 3 hr.COMMANDLIST.0 = "foo" hr.COMMANDLIST.1 = "bar" hr.COMMANDLIST.2 = "dubidu"
Das ARexx–Programm kann diese Liste mit einer einfachen Schleife abfragen:
help stem a. say 'Es gibt' a.commandlist.count 'Befehle im Testprogramm, und zwar:' do i=0 to a.commandlist.count-1 say a.commandlist.i end i
Um die Benennung anhand der Resultatnamen zu verdeutlichen geben Sie nun
noch help stem einzel. help
ein. Der Help–Befehl erzeugt nun nur
das Resultat COMMANDDESC
(Feld rxd->res.commanddesc
).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Wenn w�hrend der Ausf�hrung eines Kommandos Fehler auftreten, m�ssen diese an das aufrufende Programm zur�ckgegeben werden, damit dieses entsprechend darauf reagieren kann.
ARexx bietet dazu normalerweise nur die Variable RC
, die einen
ganzzahligen Fehlercode enthalten kann, per Konvention im Bereich
0 bis 20.
Die ARexxBox bietet hier eine etwas erweiterte M�glichkeit �ber eine automatisch generierte weitere Variable namens RC2. In dieser Variable k�nnen sowohl Fehlercodes als auch Fehlerstrings (Beschreibungen) zur�ckgegeben werden, die dann vom ARexx–Programm abgefragt werden k�nnen.
Diese beiden Variablen entsprechen den Elementen rc und rc2, die in jeder Transferstruktur existieren. Ob der Inhalt von rc2 ein Integerwert oder die Adresse eines Strings ist, wird durch das Vorzeichen von rc bestimmt: Wenn rc negativ ist, ist rc2 ein String.
Beispiel f�r Integerr�ckgabe (am Besten wo m�glich DOS–Fehlercodes verwenden):
rd->rc = 10; rd->rc2 = ERROR_NO_FREE_STORE;
Beispiel f�r Stringr�ckgabe:
rd->rc = -10; rd->rc2 = (long) "Prompt option not yet implemented";
In Oberon wird hier (wie in ‘C’) nur die Adresse des Strings �bergeben, da er normalerweise konstant ist. Also:
rd.rc = -10; rd.rc2 = SYSTEM.ADR("Prompt option not yet implemented");
Ein Integer wird als String zur�ckgegeben, Strings werden ohne Ver�nderung an ARexx �bergeben. Wenn rc negativ ist, wird das Vorzeichen vor der R�ckgabe umgedreht.
Diese erweiterte Fehlerr�ckgabe steht zwar nicht im Style Guide, ist meines Erachtens aber praktischer als der einfache Fehlercode in RC, da man so detaillierte Fehlerursachen mit zur�ckgeben kann.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Es empfiehlt sich, Applikationen objektorientiert von innen nach au�en zu entwickeln. Im Idealfall besteht eine Applikation aus einem bestimmten Kern der eigentlichen Funktionen und einer Schicht von darauf aufsetzenden Funktionen, die zwischen dem Kern und der Au�enwelt vermitteln.
Bei so einem Design reicht es, eine Schicht f�r die graphische Benutzeroberfl�che zu implementieren — die Schicht f�r ARexx besteht dann aus den von der ARexxBox generierten und von Ihnen ausgef�llten Rexx–Interfacefunktionen. Weitere Interface–Schichten sind denkbar, z.B. f�r Terminals an der seriellen Schnittstelle, ...
Wenn ein Kern von Basisfunktionen existiert, vereinfacht das die Implementation der ARexx–Schicht stark.
Ein einfaches Beispiel: Wenn eine Applikation Dateien �ffnet, kann z.B. eine Kernfunktion vorhanden sein, die nur den kompletten Dateinamen bekommt und das gesamte Einlesen der Datei vornimmt, eventuelle Fehler durch definierte R�ckgabewerte an den Aufrufer zur�ckgibt.
Die GUI–Schicht enth�lt dann eine Funktion, die vom Window–Dispatcher aufgerufen wird, wenn der Benutzer aus dem Projekt–Men� den Punkt “Open” anw�hlt. Diese Funktion �ffnet dann z.B. einen FileRequester um den Namen zu ermitteln und ruft dann die Kernfunktion auf, gibt eventuelle Fehler wiederum �ber einen geeigneten Requester an den Benutzer weiter.
Die entsprechende Routine in der ARexx–Schicht kommt mit weniger aus, da sie in der Regel den Namen der zu �ffnenden Datei als Parameter bekommt. Sie mu� also nur einen Parameter–Check vornehmen und ruft dann ihrerseits genauso die Kernfunktion auf. Eventuelle Fehler werden dann durch den R�ckgabecode an ARexx weitergeleitet.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Dieses Beispiel soll nicht das perfekte Schichtendesign wie oben vorgeschlagen demonstrieren, sondern nur die Anwendung der ARexxBox–Routinen.
Am Besten holen Sie sich nun das File ‘test/test.c’ in den Editor und sehen sich dort die Realisierung der folgenden Schritte an.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die einzige Library, die f�r die ARexxBox ge�ffnet werden mu�, ist die
rexxsyslib.library
. Es ist nat�rlich sinnvoll, einen Parameter zu
erlauben, mit dem der Benutzer den Namen des ARexxPorts bestimmen kann.
Wenn eine Routine angemeldet werden soll, die bei Resultaten von mit
SendRexxCommand() abgesetzten Kommandos aufgerufen werden soll, sollte das
zu Anfang durch die Zuweisung der Adresse der Routine an die Variable
ARexxResultHook
geschehen. In Oberon �berschreiben Sie hierf�r
einfach die abstrakte Methode HandleResult in einem geeigneten Modul
des Projekts.
Um einen ARexx–Port zu �ffnen und alle notwendigen Initialisierungen vorzunehmen wird nun SetupARexxHost() aufgerufen.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die CommandShell ben�tigt einen Ein– und einen Ausgabekanal. Im Beispiel wird eine Konsole (Fenster) daf�r ge�ffnet, es w�ren auch ganz normale Dateien daf�r denkbar (z.B. um Skripte auszuf�hren).
Die CommandShell selbst l�uft synchron, der Aufruf kehrt also erst zur�ck, wenn in der Eingabe der CommandShell EOF aufgetreten ist.
F�r das Schlie�en der Ein– und Ausgabekan�le ist nat�rlich der Aufrufer zust�ndig.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Wie man sieht, ist das Absetzen von Kommandos an ARexx sehr einfach.
Wenn Sie mehrere asynchrone Kommandos auch beim ResultHook unterscheiden wollen, dann m�ssen Sie selbst daf�r sorgen, da� Sie die in beliebiger Reihenfolge eintreffenden Resultate auch den entsprechenden vorher abgesetzten Kommandos zuordnen k�nnen.
Eine M�glichkeit ist, die Adresse der ARexxMessage zu speichern und nachher im ResultHook zu vergleichen. Eine andere ist es, die ungenutzten ARG–Felder der RexxMessage zu verwenden um dort eine Kennung anzubringen. In diesem Fall m�ssen Sie die Funktion von SendRexxCommand selbst durch die Benutzung der beiden elementaren Funktionen CreateRexxCommand und CommandToRexx nachbilden.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In einer Endlosschleife wird nun auf das Eintreffen von Signalen gewartet. Wenn eines vom ARexx–Port kommt, wird die Funktion ARexxDispatch() aufgerufen, die alles weitere erledigt.
Der gleiche Aufbau (Signal -> Dispatcher) eignet sich nat�rlich auch hervorragend f�r die Signale von Fenstern, also f�r die graphische Benutzeroberfl�che (siehe oben: GUI–Schicht).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Der Abschlu� wird im Beispiel indirekt (per atexit wurde closedown als Endroutine angemeldet) vorgenommen. Achtung, die R�ckkehr von CloseDownARexxHost() kann sich verz�gern, wenn noch Replies ausstehen. In dem Fall kann au�erdem die in ARexxResultHook eingesetzte Routine noch aufgerufen werden!
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Im folgenden gibt der Autor des Oberon-2–Source (hartmut Goebel) einige Hinweise zu dessen Konzept, Implementation und zu einigen Design-Entscheidungen.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Ziel bei der Erstellung des Oberon-2–Sources war es, dem Programmierer, der ARB benutzen will, volle Typsicherheit und den Komfort von Oberon (z.B. GarbageCollector) zu erhalten. Dies war f�r mich teilweise eine Herausforderung, da die Parameter der Result-Struktur ja vom Resultat-Template abh�ngt, zur Compile-Time also nicht allgemein gepr�ft werden k�nnen (3).
Ein weiteres wichtiges Ziel war es, auf die Klassen-Bibliothek PortHandle aufzusetzten, die sich gerade in der Entwicklung befand, als ich den Oberon-2–Source erstellte — einige Ideen aus ARB sind dort auch eingeflo�en.
Aus diesem Ziel folgt zwangsl�ufig — aber zwanglos :-) —, da� der Source auch objektorientiert gestaltet wurde. Dies bot sich auch an, da fast alle Prozeduren, die ARB erzeugt, den aktuellen RexxHost als Parameter mitbekommen. Lediglich die Interface-Funktionen wurden nicht als Methoden realisiert, da sie sonst nicht generisch ermittelt und aufgerufen werden k�nnten.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
W�hrend die Parameter von Dos.ReadArgs() geparset und in der entsrechenden Struktur zur Verf�gung gestellt werden (siehe ’ReadArgs’), erledigt das f�r die Resultate ARBRexxHost. Dies bot die M�glichkeit, wenigstens f�r letztere die volle Oberon-Typsicherheit und denn vollen Oberon-Komfort zu erhalten.
Damit sie dies auch nutzen k�nne, hier einge n�here Informationen:
Es gilt folgende Typ�quivalenz f�r die Resultate (Typbezeichner sind wieder aufgel�st):
FOOBAR
-> BasicTypes.DynString;
FOOBAR/M
-> POINTER TO ARRAY OF BasicTypes.DynString;
FOOBAR/N
-> POINTER TO ARRAY 1 OF LONGINT;
FOOBAR/N/M
-> POINTER TO ARRAY OF LONGINT;
Wie zu sehen ist, werden /M-Resultate als dynamische Arrays spezifiziert. Sie brauchen dieses lediglich mit der ben�tigten Anzahl Elemente zu allozieren und die Daten dort eintragen. Also z.B.
NEW(rx.res.foobar,10);
f�r 10 Elemente.
Da in Oberon-2 die Anzahl der Elemente leicht zu ermitteln ist,
entf�llt das abschlie�ende NIL wie in ‘C’. Dies ist auch der Grund,
weshalb bei /M/N-Resultaten direkt eine ARRAY OF LONGINT
benutzt wird und kein ARRAY OF POINTER TO LONGINT
. Letzteres
macht die Schnittstelle zwar etwas inkonsistent, daf�r aber
wesendlich komfortabler.
Parameter und einfache numerische Resultate wurden als POINTER
TO ARRAY 1 OF CHAR
deklariert, das Oberon keine Zeiger auf
unstrukturierte Typen zul��t (obwohl AmigaOberon dies tut).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Durch das Design und schon durch die Sprache ist die ‘C’-Dokumentation f�r den Oberon-Source nur bedingt geeignet. Dies betrifft insb. die Prozeduren, die in der Klassen-Bibliothek PortHandle und deren Erweiterung ARBRexxHost definiert wurden.
Ich verwiese daher auf die Dokumentation zu dieser Bibliothek. Dort sollten alle ben�tigten Informationen zu finden sein. Falls nicht, bitte ich um eine kurze Mitteilung, damit ich sie erg�nzen kann.
hartmut Goebel
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ReadArgs() benutzt Templates in Textform und schreibt die erkannten Argumente in ein Array von Langw�rtern, die vom Programm je nach Typ des korrespondierenden Arguments interpretiert werden m�ssen.
Beispiel: Ein Template “DATEI,ARG1,FORCE” bedeutet, da� drei Argumente m�glich sind. Demzufolge mu� man als Zielarray f�r ReadArgs() ein Array von mindestens drei Langw�rtern zur Verf�gung stellen.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ReadArgs() erlaubt f�nf grundlegende Datentypen, die durch entsprechende Switches im Template gekennzeichnet werden:
/N
/S
f�r Switch oder /T
f�r Toggle
/M
- Listen von Strings und Integers werden unterst�tzt
Wichtig ist hierbei, da� jedes Argument optional ist, es sei denn, der
Switch /A
(f�r Always) kommt im Template vor.
Beispiel: FILE/A,LINES/N,STDIN/S
bedeutet, da� hier drei Argumente
m�glich, aber nur das erste ben�tigt werden. Dabei ist das erste Argument
ein String, das zweite ein Integer und das dritte ein Bool.
Weiterhin ist es m�glich, f�r beliebige Argumente die Angabe des Namens als
Schl�ssel zu erzwingen. Das geschieht mit dem zus�tzlichen Switch
/K
. Au�erdem sind Aliases m�glich, d.h. da� mehrere Namen dasselbe
Argument bezeichnen.
Beispiel: FILES/M/A,AS=TO/K/A
ist das Template f�r den Join–Befehl.
Hier wird verlangt, da� die Zieldatei vom Anwender konkret gekennzeichnet
wird. F�r dieses Schl�sselwort kann der Anwender genausogut ‘AS’ wie ‘TO’
verwenden. G�ltige Eingaben f�r dieses Template w�ren z.B.:
Datei1 Datei2 as ram:Ziel
foo bar test to blafasel
as=ram:test source1 source2 source3 source4
Hierbei sehen Sie auch, da� ReadArgs() bei Angabe des Schl�sselwortes keine bestimmte Reihenfolge der Argumente mehr ben�tigt. Au�erdem ist die Schreibweise ‘KEYWORD DATA’ �quivalent zu ‘KEYWORD=DATA’.
Die Forderung nach der Angabe des Schl�sselwortes f�r bestimmte Parameter ist in vielen Situationen, die Multiple Argumente erlauben, zwingend notwendig, da ReadArgs() sonst diese Argumente nicht von der Liste der Parameter f�r ein Multi–Argument unterscheiden k�nnte.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Da die einzelnen Parameter optional sein k�nnen werden nicht direkt Objekte des jeweiligen Typs, sondern Zeiger darauf zur�ckgegeben.
Strings werden als Zeiger auf Character zur�ckgegeben. Numerische Werte werden als Zeiger auf Langworte zur�ckgegeben. Nur Bool’sche Werte werden direkt als Langworte zur�ckgegeben.
Listen werden als Zeiger auf ein Array von Zeigern zur�ckgegeben. Das Ende einer Liste wird durch einen NULL–Zeiger gekennzeichnet.
Konkret bedeutet das (f�r C):
String
⇒ char *
Stringarray
⇒ char **
Integer
⇒ long *
Integerarray
⇒ long **
Boolean
⇒ long
F�r Oberon wurden im Module ARBRexxHost entsprechende Typen vordefiniert. Da sie denen des C-Beispiele entsprechen, wird hier nicht n�her darauf eingegangen.
Zur Verdeutlichung ein Beispiel: Dem Template
FILES/M/A,AS=TO/K/A,FORCE/S,MAX/N,SOUND/T,LINES/N/M
w�rde folgende
Datenstruktur als R�ckgabestruktur entsprechen:
struct readargs_result { char **files; char *to; long force; long *max; long sound; long **lines; } rda_result;
(Anmerkung: Dieses Template ist nicht einwandfrei in Ordnung und dient nur dazu, die Typgebung zu verdeutlichen - tats�chlich sollte in einem Template nur ein </M>–Switch vorkommen.)
Die einzelnen Felder kann man vor dem ReadArgs–Aufruf mit Defaultwerten f�llen, ReadArgs ver�ndert nur die Felder, f�r die tats�chlich Argumente angegeben wurden. F�r Boole’sche Felder gilt eine andere Regelung: /S–Felder werden immer entsprechend dem Vorhandensein des Keywords gesetzt, Toggle–Felder (/T) drehen den vorher eingesetzten Default–Wert bei Vorhandensein des Keywords um — theoretisch. Praktisch habe ich das noch nie ausprobiert, kann also nicht daf�r garantieren 8-).
Bei Strings und Integern kann man also anhand des prim�ren Zeigers in der obigen Struktur erkennen, ob der Parameter �berhaupt spezifiziert wurde, ansonsten ist der Zeiger NULL.
Arrays k�nnen beliebig gro� werden, daher wird das Ende durch den ersten Arrayeintrag, der NULL ist, gekennzeichnet.
Boole’sche Werte werden immer gesetzt, wenn im Template </S> verwendet wurde, und zwar bedeutet die Anwesenheit des Schl�sselwortes im Kommando, da� der Bool–Wert auf 1 gesetzt wird, ansonsten 0. Toggle–Bools (mit </T>) drehen den voreingestellten Wert um.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Es gibt noch einen weiteren Switch, </F>, der benutzt wird, um einem Argument den gesamten Rest der Kommandozeile ab der Stelle zuzuweisen, selbst wenn andere Schl�sselw�rter darin vorkommen. Dieser Switch ist in der Regel unn�tig und mit Vorsicht zu genie�en.
Parameter, die nicht durch Anf�hrungszeichen explizit vom Anwender als solche gekennzeichnet wurden, werden bei �bereinstimmung mit einem Argument zun�chst als Schl�sselw�rter betrachtet. So wird die Eingabe “foo bar all qwe” zu einem Template “Dir/M,All/S” den Switch ALL setzen und in DIR das Array “foo”, “bar”, “qwe” zur�ckgeben. W�re in der Eingabe “all” in Anf�hrungszeichen, dann w�rde der String “all” mit in das Array aufgenommen und der Switch ungesetzt bleiben.
Wie schon oben angedeutet sollte man nicht mehr als ein Array (</M>) pro Template verwenden, da ReadArgs sonst Probleme mit der Verteilung der freien Parameter auf die Argumentfelder bekommt.
Wenn nach dem Parsen noch unbesetzte /A–Argumente verbleiben, werden von einem /M–Argument daf�r vom Ende des Arrays Strings abgezogen. Ein Beispiel hierf�r ist der Copy–Befehl: Das Template “From/A/M,To/A” weist bei der Eingabe “copy file1 file2 file3 destination” das letzte Wort dem TO–Feld zu.
Zu ReadArgs siehe auch ‘AutoDocs:dos.doc’.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/ARexxDispatch ARexxBox/ARexxDispatch NAME ARexxDispatch -- get ARexx command from MsgPort and execute it SYNOPSIS ARexxDispatch( rexxhost ); void ARexxDispatch( struct RexxHost * ); FUNCTION ARexxDispatch fetches and executes all queued commands from the given RexxHost's message port. If a reply for some previously (with SendRexxCommand()) sent command comes in, the counter variable for still outstanding replies will be decreased by one and the RexxMsg and it's associated memory will be freed by FreeRexxCommand(). In the main program, you should just check for the signal of the host's message port and call ARexxDispatch() without actually getting the message. All work will be done by the dispatcher. INPUTS rexxhost - pointer to an active RexxHost structure with a valid MsgPort RESULTS SEE ALSO SendRexxCommand(), SetupARexxHost(), DoShellCommand()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/CloseDownARexxHost ARexxBox/CloseDownARexxHost NAME CloseDownARexxHost -- close & free ARexx host SYNOPSIS CloseDownARexxHost( rexxhost ); void CloseDownARexxHost( struct RexxHost * ); FUNCTION CloseDownARexxHost() waits until replies for all pending ARexx commands have been received and then closes the ARexx port and frees all memory associated with that RexxHost structure. All messages sent to a closing host will be replied immediately with an error "Host closing down". INPUTS rexxhost - the RexxHost to close down RESULTS SEE ALSO SetupARexxHost(), SendRexxCommand()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/CommandShell � ARexxBox/CommandShell NAME CommandShell -- process Commands from a file SYNOPSIS CommandShell( rexxhost, fhin, fhout, prompt ); void CommandShell( struct RexxHost *, BPTR, BPTR, char * ); FUNCTION CommandShell() sets the Flag ARB_HF_CMDSHELL in the RexxHost's flag field and then processes input from fhin until EOF or the CmdShell flag in the RexxHost being cleared (e.g. by the standard Rexx command "CMDSHELL CLOSE"). The input is read line-wise, with newline as EOL. Each line will be parsed and executed just like a built-in custom ARexx command, exactly like it was called via an ARexx host messageport. The parsing and execution of each line is done by the function DoShellCommand(). If fhout is not NULL, the output of the commands will be printed to fhout. The output of the commands will NOT be assigned to any variables, as there is no underlying ARexx script program that could hold these variables. Instead, the output will be formatted to be human-readable. The prompt string (if not NULL) will be printed to fhout as an input request before reading an input line. New (ARB 0.99d): The rexxhost parameter has to point to a valid RexxHost structure. This is for identifying which command shell belongs to which window/instance of the main process. New( ARB 0.99e): To support the "RX" command sending asynchronous messages to ARexx, this function now catches the replies of those messages and frees them using FreeRexxCommand(). Messages sent _to_ this host will be replied immediately with an error "CommandShell Port". INPUTS rexxhost - an initialized RexxHost structure fhin - the input FileHandle (see dos.library/Open()) fhout - the output FileHandle (or NULL) prompt - the prompt string (or NULL) RESULTS SEE ALSO DoShellCommand(), ARexxDispatch(), dos.library/Open()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/CommandToRexx �ARexxBox/CommandToRexx NAME CommandToRexx -- send a prepared RexxMsg to the ARexx server SYNOPSIS msg = CommandToRexx( rexxhost, rexxmessage ); struct RexxMsg *CommandToRexx( struct RexxHost *, struct RexxMsg * ); FUNCTION CommandToRexx just sends the given RexxMsg to the ARexx server process without changing any fields of the Msg. It will also increment the counter for outstanding replies in the RexxHost structure. You can use this function together with CreateRexxCommand() to easily create customizable command messages for Rexx. INPUTS rexxhost - an initialized RexxHost structure rexxmessage - an initialized ARexx message RESULTS msg - the same as rexxmessage, just for easy further processing SEE ALSO CreateRexxCommand(), SendRexxCommand()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/CreateRexxCommand ARexxBox/CreateRexxCommand NAME CreateRexxCommand -- allocate & initialize rexxmsg for a command SYNOPSIS rexxmsg = CreateRexxCommand( rexxhost, command, fh ); struct RexxMsg *CreateRexxCommand( struct RexxHost *, char *, BPTR ); FUNCTION This function will create a RexxMsg structure for the given RexxHost, create an Argstring from the command string and use that string to initialize the message as a RXCOMM type with RXFF_RESULT requested. The file handle will be used for both input and output. You can use this function to create a standard ARexx command with the additional possibility to set some extra parameters before sending the command to ARexx using CommandToRexx(). INPUTS rexxhost - an initialized RexxHost structure command - the command string fh - the input/output FileHandle (see dos.library/Open()) RESULTS rexxmsg - a pointer to the new RexxMsg structure SEE ALSO CommandToRexx(), SendRexxCommand(), dos.library/Open()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/DoShellCommand ARexxBox/DoShellCommand NAME DoShellCommand -- parse & execute a command line SYNOPSIS DoShellCommand( rexxhost, commandline, fhout ); void DoShellCommand( struct RexxHost *, char *, BPTR ); FUNCTION DoShellCommand parses the given string assuming it contains an ARexx-style command line. New (ARB 0.99e): If normal parsing fails, the external function ExpandRXCommand() will be called to expand any macros. If the expansion fails or the expanded command can't be recognized either, an error will be returned. If no errors occur during parsing, it tries to execute the command with the given arguments. The results of the command's execution will be printed in a human-readable format to fhout if fhout is not NULL. If errors occur, DoShellCommand prints a string describing the error to fhout (if not NULL). New (ARB 0.99d): The rexxhost parameter has to point to a valid RexxHost structure. This is for identifying which command shell belongs to which window/instance of the main process. INPUTS rexxhost - an initialized RexxHost structure commandline - the string to be parsed & executed fhout - the output FileHandle (or NULL) RESULTS none SEE ALSO CommandShell(), ExpandRXCommand(), <dos/dos.h>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/ExpandRXCommand ARexxBox/ExpandRXCommand NAME ExpandRXCommand -- expand macros and/or aliases (V0.99e) SYNOPSIS newcommand = ExpandRXCommand( rexxhost, oldcommand ) char *ExpandRXCommand( struct RexxHost *, char * ); FUNCTION This is an 'external' function you should provide if you want to have command aliases or the like. The minimal version of this function is just a return(NULL) as generated in the rxif module. ExpandRXCommand() will be called by the parser if it doesn't know how to interpret a command string. Expansion could now for example be a look up in the host's macro table. Any strings returned by this function have to be allocated explicitly using the standard C memory functions. The calling parser will free() them. INPUTS rexxhost - the RexxHost we are working on oldcommand - the commandline the parser doesn't know RESULTS newcommand - an explicitly allocated memory area con- taining the expanded command (or NULL) SEE ALSO DoShellCommand(), ARexxDispatch()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/FindRXCommand ARexxBox/FindRXCommand NAME FindRXCommand -- search the ARexxBox command table (V0.99e) SYNOPSIS rxscmd = FindRXCommand( command ) struct rxs_command *FindRXCommand( char * ); FUNCTION This function returns a pointer to the given command's entry in the ARexxBox-generated command table. It exists to support those functions working on/with commands, like HELP or ENABLE/DISABLE. This function does no macro expansion. The comparisons are case independant so you don't have to convert your input to upper case beforehand. As this is exactly the routine used by the parser to find a command, it will handle abbreviations. INPUTS command - the command name to search for RESULTS rxscmd - the rxs_command structure of that command (or NULL if command not found) SEE ALSO
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/FreeRexxCommand ARexxBox/FreeRexxCommand NAME FreeRexxCommand -- free the associated memory of a RexxMsg SYNOPSIS FreeRexxCommand( rexxmessage ); void FreeRexxCommand( struct RexxMsg * ); FUNCTION This is basically a PD ARexx routine provided by William S. Hawes. It frees all memory associated with a particular (previuosly sent) ARexx message structure. It will also close any stdin/stdout channels associated to that Rexx message. You normally shouldn't have to bother with this one because the dispatcher will call it for you. INPUTS rexxmsg - the rexx message to free RESULTS SEE ALSO SendRexxCommand()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/ReplyRexxCommand ARexxBox/ReplyRexxCommand NAME ReplyRexxCommand -- reply a rexx message from rexxmast SYNOPSIS ReplyRexxCommand( rexxmsg, primary, secondary, result ); void ReplyRexxCommand( struct RexxMsg *, long, long, char * ); FUNCTION This is a PD ARexx routine provided by William S. Hawes. It replies a given rexx message to the rexx master process, filling in a primary and a secondary return code plus optionally a supplied result string. The result string will only be converted to an ARexx string, if the primary return code equals 0, and will then destroy the contents of the secondary return code. So you provide either primary and secondary return codes or a result string. You normally shouldn't have to call this function! It is only mentioned here, because it is not part of the ARexxBox routines, but part of the original ARexx distribution by William S. Hawes. New (ARB V0.99d): Now creates an ARexx variable "RC2" for the secondary return code. If primary is positive, secondary is interpreted as a long, if primary is negative, secondary is interpreted as a char *. RC will become positive in any case. RC2 will only be assigned if the ARexx RESULT flag is set. INPUTS rexxmsg - the message structure to reply primary - the primary return code (rc) ( >0 <0 ) secondary - the secondary return code (rc2) (long or char *) result - the result string RESULTS SEE ALSO SendRexxCommand(), FreeRexxCommand()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/SendRexxCommand ARexxBox/SendRexxCommand NAME SendRexxCommand -- invoke rexx command script SYNOPSIS rexxmsg = SendRexxCommand( rexxhost, command, filehandle ) struct RexxMsg *SendRexxCommand( struct RexxHost *, char *, BPTR ); FUNCTION This is basically a PD ARexx routine provided by William S. Hawes. This function sends the given command string to the ARexx master process for execution as an ARexx command. The command string contains the file name of the ARexx script to be started. If the filehandle is not NULL, it will be used as stdin and stdout for the Rexx script. If it is NULL, the Rexx program will use stdin/stdout of the calling process. If necessary, the default extension (defined in the generated header file under the name REXX_EXTENSION) will be added to the file name. Messages sent using this function will be replied to by the ARexx master process as soon as the execution of the command script stops. The application MUST NOT close it's messageport before all replies have been received! To simplify things, ARexxBox does this book-keeping for you. CloseDownARexxHost() will wait for all missing replies to arrive before closing down the messageport. The dispatcher will automagically detect any replies, count them and do a FreeRexxCommand() for each reply, so you don't have to bother with this either. Internally, this function is implemented using the two more atomic functions CreateRexxCommand() and CommandToRexx(). INPUTS rexxhost - the RexxHost to be used to send the command command - the file name of the ARexx script filehandle - Filehandle for stdin/stdout or NULL RESULTS rexxmsg - the sent rexx message structure (for comparisons) SEE ALSO FreeRexxCommand(), CloseDownARexxHost(), ARexxDispatch(), CreateRexxCommand(), CommandToRexx()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/SetupARexxHost ARexxBox/SetupARexxHost NAME SetupARexxHost -- initialize and open an ARexx host SYNOPSIS rexxhost = SetupARexxHost( basename ); struct RexxHost *SetupARexxHost( char * ); FUNCTION This function allocates and initializes a RexxHost structure. It opens a public message port under the given basename. If no basename (NULL) was specified, the default basename as entered in the ARexxBox window will be used instead. Anyway, if a public port of that name already exists, SetupARexxHost() will start adding numbers to the name until a unique name is found. So if for example the basename is "myhost" and there is already a port of that name in the system, the name will be changed to "myhost.1" (then to "myhost.2" and so on). The actual name will be copied to the portname field of the RexxHost structure. It is a good idea to tell the user about the actual port name of the new host. INPUTS basename - the messageport basename or NULL RESULTS rexxhost - the initialized RexxHost structure, ready to go. Pass this pointer to CloseDownARexxHost(), ARexxDispatch() and SendRexxCommand(). SEE ALSO CloseDownARexxHost(), ARexxDispatch(), SendRexxCommand()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ARexxBox/StrDup ARexxBox/StrDup NAME StrDup -- duplicate a string SYNOPSIS copy = StrDup( origin ); char *StrDup( char * ); FUNCTION This routine will do exactly the same as its standard C lib counterpart strdup(), but use the exec function AllocVec() for allocating the needed memory. (So YOU are responsible for freeing the copy!) INPUTS origin - the original string RESULTS copy - the copy of the original string SEE ALSO strdup(), exec.library/AllocVec(), exec.library/FreeVec()
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In diesem Kapitel wird das Dateiformat der ARexxBox erkl�rt, und was man dabei beachten sollte, um eine externe Nutzung der ARB–Dateien zu erm�glichen. Sie k�nnen somit z.B. selbst weitere Sourcegeneratoren schreiben.
Das ARB–Datenformat ist ein erweiterbares ASCII–Format (Zeilentrenner ist LF). Neben den offensichtlichen Daten (Syntax der Befehle, Argumente und Resultate) enth�lt eine ARB–Datei zus�tzlich allgemeine und befehlsspezifische Tags.
ARB–Dateien enthalten zwecks Identifizierung als erste Zeile den String
ARB
. Ab Zeile zwei steht der erste, globale Tag–Block. Jede
Tagzeile f�ngt mit einem Dollarzeichen an, dem ohne Leerraum die Tag–ID
(Typ long) folgt. Der Tag–ID folgen dann — durch Spaces getrennt —
entsprechend der Tag–ID noch weitere alphanumerische Parameter.
Bislang existiert nur eine globale Tag–ID:
Die erste Zeile nach diesem Tagblock enth�lt den MsgPort–Basisnamen. Die n�chste Zeile enth�lt den Status des CommandShell–Gadgets (1 f�r angew�hlt). Dann folgen die Befehle. Jeder Befehl hat die folgende Struktur:
$
, gefolgt von der Tag–ID wie
oben)
Bei den Befehlen existieren bislang zwei Tag–IDs:
Bitte beim Einlesen darauf achten, da� in zuk�nftigen Versionen der ARexxBox die Tagbl�cke erweitert werden k�nnen. Die Leseroutine f�r die Tags sollte mit einer beliebigen Anzahl von Tagzeilen zurechtkommen und unbekannte Tags zumindest ignorieren.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
History of ARexxBox Releases:
V0.99 erster Beta-Release V0.99a FIXED: Argument- und Resultat-Liste konnte mit ung�ltigem Kommando arbeiten -> Enforcer-Hit/Absturz. (Report: RALF_KAISER@AWORLD) V0.99b ENHANCED: GadToolsBox-Source fixed um den System Default Font statt des Screenfonts f�r Layout und Gadgets zu benutzen. (Report: SYSOP@INSIDER [Garry Glendown]) V0.99c FIXED: F�r Argumente wurde das Gleichheitszeichen nicht zugelassen. FIXED: Nach �nderung eines Argumentes oder Resultates verbleibt die Anzeige auf diesem Element statt (wie bisher) das letzte Listenelement anzuzeigen. FIXED: In den Font-Routinen war noch ein Fehler. (Report: F.J.Reichert [F_J_REICHERT@SAARAG]) V0.99d FIXED: Alle Pointer-Conversions bereinigt. Der Code wird jetzt selbst bei Compiler 'superscharf' v�llig ohne Warnings durchgezogen. Pragma-#includes und _toupper() nun auch f�r SAS/C drin. (Report: W_KUETING@HSP) --- V0.99d wurde nicht verteilt! --- V0.99e FIXED: Wenn _kein_ Resultatfeld belegt war, wurde ein "out of memory"-Fehler erzeugt. ENHANCED: ReplyRexxCmd() erzeugt nun die Variable RC2, sie enth�lt den "Secondary Returncode", der in jeder rxif-Struktur unter dem Namen rc2 steht. Diese Variable kann z.B. benutzt werden, um detaillierte Fehlercodes an das Rexxprogramm zur�ckzugeben. Dieses Feature ist eine Erweiterung der Style-Guide- Richtlinien, m.E. eine sinnvolle. Wenn jemand anderer Ansicht ist, bitte Mail an mich! RC2 wird nur erzeugt, wenn a) Resultate erw�nscht sind und b) RC != 0 ist. Das Feld rc2 kann sowohl einen Fehlercode (long, default) als auch eine Fehlerbeschreibung (char *) enthalten. Unterschieden wird anhand des Vorzeichens von rc, d.h. rc < 0 <=> rc2 long bzw. rc > 0 <=> rc2 char *. Negatives rc wird vor der R�ckgabe nach positiv gewandelt. Beispiel f�r FehlerCODE: rd->rc = 10; rd->rc2 = ERROR_OBJECT_NOT_FOUND; Beispiel f�r FehlerSTRING: rd->rc = -10; rd->rc2 = (long) "Objekt nicht gefunden!"; Die Standard-Fehlerstrings sind _nicht_ lokalisiert. Wenn sich C= mal bequemt, mir Infos und Werkzeuge daf�r zu schicken, werde ich das nat�rlich nachholen. ENHANCED: SendRexxCommand() nimmt jetzt zur besseren Unterst�tzung des Standardbefehls "RX" (zum Starten von ARexx-Programmen) einen zus�tzlichen Parameter, ein FileHandle (BPTR!), der als Stdin/Stdout f�r das Script eingesetzt wird. FreeRexxCommand() �bernimmt das Schlie�en des Kanals. Au�erdem liefert SendRexxCmd() nun die Adresse der abge- schickten RexxMsg zur�ck (oder NULL wenn Fehler). ENHANCED: Die RexxHost-Struktur hat jetzt ein zus�tzliches Feld namens "APTR userdata". Es kann z.B. benutzt werden, um in einen RexxHost einen Zeiger auf eine eigene Projekt- Verwaltungs-Struktur einzuh�ngen o.�., um den Host ein- deutig einem offenen Projekt zuzuordnen. ENHANCED: Jeder Befehl hat jetzt ein globales "enabled"- Flag, wenn dies gel�scht ist, verweigert der Dispatcher die Ausf�hrung des Befehls. Dieses Flag sollte mit den Standard-ARexx-Befehlen (Style Guide) ENABLE und DISABLE beeinflussbar sein (siehe rxif/*.c). CHANGED: CommandShells ben�tigen jetzt einen eigenen RexxHost auf dem sie alleine arbeiten k�nnen. D.h. der daf�r bereitgestellte Host DARF NICHT gleichzeitig als normaler ARexx-Port benutzt werden. Eine abwechselnde Benutzung als ARexx- und Cmd-Port ist denkbar, aber nicht empfehlenswert... ENHANCED: Damit einhergehend bekommt nun jede rxif-Funktion den RexxHost des ARexx-Ports bzw. der CmdShell als (ersten) Parameter (host) �bergeben. Dadurch kann die Funktion z.B. entscheiden, zu welchem Projekt der Befehl ausgef�hrt werden soll. ENHANCED: Ebenfalls damit einhergehend existiert jetzt zur Unterst�tzung des Standardbefehls CMDSHELL in jedem RexxHost ein Flag (ARB_HF_CMDSHELL), das anzeigt, ob der Host gerade eine CommandShell f�hrt. Wenn dieses Flag (durch CMDSHELL CLOSE) gel�scht wird, terminiert die ARexx- Box die CommandShell. FIXED: Aus Spaces oder nur aus Optionen bestehende Argument- bzw. Resultatfeldnamen werden nicht mehr akzeptiert. CHANGED: Da einige rxif-Funktionen darauf zugreifen m�ssen ist "struct rxs_command" und "rxs_commandlist" nun im Headerfile definiert. F�r den Zugriff auf die Liste (finden eines Kommandos) ist eine neue Funktion da: struct rxs_command *FindRXCommand( char *name ); FIXED: Argumente mit '=' wurden nicht korrekt in C-Variablennamen umgesetzt. Nun wird der letzte Alias als Variablenname benutzt. ENHANCED: Es gibt jetzt eine eigene Handlerfunktion f�r dem Parser unbekannte Kommandos: char *ExpandRXCommand( struct RexxHost *host, char *commandline ); Diese wird aufgerufen, bevor der Parser "Not implemented" als Fehler ausgibt. Wenn die Funktion NULL zur�ckgibt, wird der Fehler ausgegeben, ansonsten versucht der Parser, den zur�ckgegebenen String zu analysieren. Diese Funktion kann z.B. die Expansion von Aliases oder die Bearbeitung von Non-Standard-Kommandos �ber- nehmen. Achtung! Es wird erwartet, da� Expand() eigens Speicher f�r den Resultatstring allokiert, dieser wird von den ARB-Routinen dann freigegeben! ENHANCED: Die Checks beim Generieren der Source- Module sind jetzt sicherer. Es wird nun auch auf Existenz des C- und H-Moduls gepr�ft. NOTE: Als ich die vom Style Guide vorgeschlagenen Standardkommandos eingab, sah ich, da� die Argumente "VAR" und "STEM" an einer Stelle auch dazu benutzt werden, die EINgabe der Funktion von den damit be- nannten Variablen zu holen. Ich wei� nicht, ob das so eine gl�ckliche Wahl ist, da man auf diese Art&Weise keine Resultate mehr haben kann. Besser w�re eine andere Benennung, z.B. "FROMVAR" und "FROMSTEM". Vorschl�ge? Die ARB k�mmert sich wenig um die bereits eingegebenen Argumente, wenn Resultatfelder existieren, werden VAR und STEM immer in das Template aufgenommen. Allgemein sind einige Definitionen an der Stelle im Style Guide sehr ungenau oder unzureichend. Ich habe die Definition (sinnvoll) erweitert. Wer mit meinen �nderungen nicht einverstanden ist, soll sich bitte melden. NOTE: Beim �bernehmen alter Interface-Routinen daran denken, da� ein neuer Parameter dazu gekommen ist! FIXED: Numerische Resultate funktionieren jetzt. V0.99f ENHANCED: Es werden zwei FileRequester verwendet, einer f�r Binaries und einer f�r Sourcen. Die Patterns bleiben nun erhalten und sind standardm�ssig mit #? statt *. (Report: Stefan Zeiger) FIXED: Window-Topedge ist nun Fontsensitiv. (Report: Stefan Zeiger) V0.99g FIXED: Beim Parsen der Argumente wird nun der von ReadArgs() erzeugte Fehlercode als rc2 benutzt. CHANGED: Den Templates wird nun vor dem Parsen kein \n mehr angeh�ngt (unn�tig). CHANGED: Die ARexxBox benutzt nun den ASL-Filerequester. (Wunsch: Garry Glendown [Sysop@Insider]) V1.00 ENHANCED: Source wird nun auch vom GCC fehlerfrei und warnungsfrei �bersetzt - naja, fast warnungsfrei. Die verbleibenden Warnungen k�nnen aber getrost ignoriert werden. CHANGED: FindRXCommand() akzeptiert nur noch echte Abk�rzungen der vorhandenen Befehle. --- ERSTER �FFENTLICHER RELEASE --- V1.01 ENHANCED: FindRXCommand() benutzt jetzt bin�re Suche. (also Komplexit�t O(log n) statt O(n)) V1.02 ADDED: Clipboard-Unterst�tzung FIXED: CreateVAR() pr�fte eine Allokation nicht (Report: R�diger Dreier) CHANGED: SendRexxCommand() ist nun aufgeteilt in zwei Routinen, CreateRexxCommand() und CommandToRexx(). Somit kann man die erstellte Msg bei Bedarf vor dem Versand noch ver�ndern. ENHANCED: Unbekannte Kommandos werden nun zus�tzlich noch an ARexx geschickt, bevor sie als "unbekannt" eingestuft werden. So k�nnen externe ARexx-Programme v�llig transparent aufgerufen werden. (Vorschlag: R�diger Dreier) ENHANCED: DoRXCommand() und DoShellCommand() bei der R�ckgabe ein wenig aufpoliert. (Report: Hartmut Goebel) FIXED: Der Dispatcher pr�ft nun, ob es sich bei den ankommenden Msgs wirklich um ARexx-Kommandos handelt. (Report: Hartmut Goebel) FIXED: In free_stemlist() war ein potentieller FreeMem-Bug. CHANGED: Statt (m|c)alloc und free werden jetzt AllocVec und FreeVec benutzt. Damit einhergehend ist eine neue Funktion, ein Replacement f�r strdup(), StrDup() (wie auch sonst) vorhanden. char *StrDup( char *string ) (Vorschlag: R�diger Dreier) FIXED: Der CloseDown konnte laufende Skripte, die auf dem Port arbeiteten, h�ngen lassen. (Report: R�diger Dreier) V1.03 ENHANCED: Neuer Parameter f�r die ARB: FONT=<name>/<size>, spezifiziert den Font, den die ARB benutzen soll. Default ist jetzt wieder (Style-Guide-konform) der ScreenFont. (Vorschlag: Timothy J. Aston) CHANGED: Wenn ein leerer Portname angegeben wird, wird der Defaultname benutzt. (Vorschlag: Hartmut "Essich" Goebel) CHANGED: VAR- und STEM-Parameter werden nach Gro�schreibung gewandelt, da SetRexxVar() dies anscheinend nicht selbst durchf�hrt. (Rexx-Konvention) V1.04 FIXED: Pfad des Projektfiles wird nun beibehalten wenn man zwischendurch ein File per "Merge" hereinholt. (Report: Stefan Reisner) FIXED: ARG0 wird nun �berall auf (char *) gecastet. (Report: Marc Schr�er) ENHANCED: Das Headerfile hat jetzt einen eigenen #define. (Marc Schr�er) V1.05 ENHANCED: Sourceerzeugung nun intelligenter, alte Interfaceroutinen werden anhand spezieller Kommentare im Source erkannt und entweder �bernommen oder in ein Lagerfile kopiert. (Vorschlag: Alle; ID-Idee: Christoph Teuber) CHANGED: Dateiformat ge�ndert um die neue Sourceerzeugung zu unterst�tzen. Die Box kann das alte Format weiterhin lesen, das erspart mir den Konverter (gell, Olaf? ;-). ENHANCED: SetupARexxHost() bekommt nun als zweiten Parameter einen optional vorher vom User allokierten MsgPort. So kann man sich vorher einen MsgPort f�r speziellen Bedarf (z.B. spezielles Signal) schneidern. (Vorschlag: Stefan Reisner) V1.10 ENHANCED: Die ARexxBox kann nun auch Oberon-Code erzeugen. Der Oberon-Code stammt komplett aus der au�erordentlich f�higen Feder von Hartmut "Essich" Goebel. Fragen und Vorschl�ge zum Oberon-Teil bitte an ihn, da ich mit Oberon wenig anfangen kann (und will 8-). ENHANCED: Result-Hook eingebaut, wenn man der Variablen ARexxResultHook die Adresse einer Funktion zuweist, dann wird diese f�r alle Replies zu selbst abgeschickten Msgs aufgerufen. FIXED: FreeRexxCommand() schlie�t stdin und stdout nicht mehr. Vielleicht tr�gt ja jemand aus Versehen mal diese ein (nicht NULL). V1.11 FIXED: Letzte Oberon-�nderungen eingebaut. ----------- Release 2 ------------- V1.12 FIXED: HELP-Befehl erzeugte Enforcer-Hits (strlen(0)). (Report: Klaas Hermanns) ENHANCED: Tag #2 f�r Kommandos eingef�hrt: Externes Status-Flag, "Neu"-Status dieses Flags wird nur von externen Programmen (spez. Dokumentationshilfen wie ARB2TeXinfo von Albert Weinert) zur�ckgesetzt. (Vorschlag: Albert Weinert) FIXED: Die Kommandoliste wurde in der Reihenfolge der IDs anstatt in alphabetischer Reihenfolge generiert. (Report: Klaas Hermanns) ENHANCED: Statt bin�rer Suche (f�r die Kommandos) erzeugt die Box nun doch einen endlichen Suchautomaten. Die bin�re Suche hatte den grundlegenden Designfehler, da� die Sortierung nach L�nge mit Abk�rzungen kollidierte. (Report des Fehlers: Klaas Hermanns) FIXED: F�r SAS wird toupper() #undefined, au�erdem in der CommandList die richtigen Casts f�r die Funktionen. (Report: Klaas Hermanns) FIXED: Die MIN- und MAX-Resultate von Misc.arb/GETATTR m�ssen nat�rlich Numerisch sein. (Report: Klaas Hermanns) FIXED: "Merge" baute Mist bei bestehenden Kommandos. CHANGED: Die externen Libs werden nun mit ihren erweiterten Typen deklariert (C). (Wunsch: Klaas Hermanns) CHANGED: In arb/advanced.arb habe ich bei den Kommandos REQUESTNUMBER und REQUESTSTRING jeweils das Argument "DEFAULT" in "DEFAULTNUM" bzw. "DEFAULTSTR" ge�ndert, um Konflikte mit den Schl�sselw�rtern in C zu vermeiden. (Report: Klaas Hermanns) ENHANCED: Die RXIF-Funktionen bekommen nun einen weiteren Parameter, struct RexxMsg *rexxmsg, welcher bei einem Aufruf von REXX aus den Zeiger auf die RexxMessage enth�lt (was sonst). Dies erm�glicht es, z.B. GetRexxVar() im RXIF-Code zu benutzen. Bei Aufruf von einer CommandShell enth�lt der Parameter den Wert NULL, ist somit auch als Unterscheidungsmerkmal ARexx <-> CommandShell benutzbar. (Report: Klaas Hermanns) FIXED: F�r den GCC wird nun toupper() als Funktion definiert. Das Makro f�hrte wegen mehrfacher Auswertung des Ausdrucks zu Fehlern. FIXED: Die CommandShell hatte noch einen Bug beim Parsen der Parameter (ReadArgs-Puffer wurde nicht geloescht). ----------- Release 3 -------------
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Ich m�chte mich hiermit besonders bedanken bei:
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jump to: | A B C D E F G H I K L M O P R S T U V W |
---|
Jump to: | A B C D E F G H I K L M O P R S T U V W |
---|
[Top] | [Contents] | [Index] | [ ? ] |
Der Oberon-2–Source wurde objektorientiert und “type-save” designt.
Diese Module dienen nicht nur dem von ARB erzeugten Source, sondern k�nnen nat�rlich auch in anderen Projekten verwendet werden.
Die generischen Prozeduren in ARBRexxHost (speziell ARBRexxHost.CreatStem) l�sen diesen Problem — wie ich meine — recht ellegant. Ich empfehle durchaus, sie sich einmal n�her anzusehen.
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on March 16, 2022 using texi2html 5.0.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
[ < ] | Back | Previous section in reading order | 1.2.2 |
[ Up ] | Up | Up section | 1.2 |
[ > ] | Forward | Next section in reading order | 1.2.4 |
[ >> ] | FastForward | Next chapter | 2 |
[Top] | Top | Cover (top) of document | |
[Contents] | Contents | Table of contents | |
[Index] | Index | Index | |
[ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on March 16, 2022 using texi2html 5.0.